package bancosys.tec.security.impl.dao;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import bancosys.tec.persist.dao.BaseDAO;
import bancosys.tec.persist.dao.BeanNotFoundException;
import bancosys.tec.persist.hibernate.RestrictionsUtils;
import bancosys.tec.security.impl.domain.UserAccessData;

/**
 * @author piercio
 */
public class UserAccessDataDAO extends BaseDAO<UserAccessData> {

    /**
     * Busca todos os dados de acesso de um usuário, em ordem decescente de login.
     * 
     * @param username o nome do usuário.
     * @param clientname o nome da aplicação cliente.
     * @return o {@link UserAccessData} do usuário passado.
     */
    public List<UserAccessData> findByUsernameClientname(String username, String clientname) {
        Criteria crit = this.createCriteria();
        RestrictionsUtils.addRestrictionEq(crit, "username", username);
        RestrictionsUtils.addRestrictionEq(crit, "clientName", clientname);
        crit.addOrder(Order.desc("loginTimestamp"));

        return this.executeQuery(crit);
    }

    /**
     * Busca os dados de acesso de um usuário para um session ID.
     * 
     * @param username o nome do usuário.
     * @param sessionId o id da sessão.
     * @param clientname o nome da aplicação cliente.
     * @return o {@link UserAccessData} do usuário passado.
     * @throws BeanNotFoundException caso não encontre dados do usuário na sessão.
     */
    public UserAccessData findByUsername(String username, String sessionId, String clientname) throws BeanNotFoundException {
        Criteria crit = this.createCriteria();
        RestrictionsUtils.addRestrictionEq(crit, "username", username);
        RestrictionsUtils.addRestrictionEq(crit, "sessionId", sessionId);
        RestrictionsUtils.addRestrictionEq(crit, "clientName", clientname);

        return this.executeSingleQuery(crit);
    }

    /**
     * Busca os dados do último login do usuário passado, ou <code>null</code> caso seja o primeiro acesso.
     * 
     * @param username o nome do usuário.
     * @param clientname o nome da aplicação cliente.
     * @return o último {@link UserAccessData} do usuário passado, ou <code>null</code> caso seja o primeiro acesso.
     */
    public UserAccessData findLastLoginByUsername(String username, String clientname) {
        Criteria crit = this.createCriteria();
        crit.add(Restrictions.eq("username", username));
        RestrictionsUtils.addRestrictionEq(crit, "clientName", clientname);
        crit.addOrder(Order.desc("loginTimestamp"));
        crit.setMaxResults(2);

        List<UserAccessData> result = this.executeQuery(crit);

        if (result.size() < 2) {
            return null;
        }

        // O último login é o login atual, portanto deve passar o penúltimo
        return result.get(1);
    }
}
